package org.hawk.gwt.ppc;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import org.hawk.gwt.ppc.javacc.ParseException;

/**
 * Wraps default GWT compiler into the local wrapper.
 * This allows to create some sort of metadata for the final application.
 * @author alex.bereznevatiy@gmail.com
 */
public class CompilerWrapper {
	private static final String GWT_COMPILER_CLASS_NAME = "com.google.gwt.dev.Compiler";

	/**
	 * @param args
	 * @throws ParseException 
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args) 
			throws ParseException, IOException {
		CmdArgs argsProcessor = new CmdArgs(args);
		Environment env = Environment.getInstance();
		env.configure(argsProcessor);
		try {
			main(env);
		}
		catch (NoClassDefFoundError e) {
			Log.error("Unable to find GWT compiller class in the classpath",e);
			System.exit(1);
		}
		catch(ClassNotFoundException e){
			Log.error("Unable to find GWT compiller class in the classpath",e);
			System.exit(1);
		}
		catch(Throwable ex){
			ex.printStackTrace();
			env.dispose();
			System.exit(1);
		}
	}

	private static void main(Environment env)
			throws IOException, ParseException, ClassNotFoundException,
			IllegalAccessException, InvocationTargetException,
			NoSuchMethodException {
		ClassLoader loader = CompilerWrapper.class.getClassLoader();
		try {
			ProcessingUnitsManager manager = ProcessingUnitsManager.getInstance();
			manager.run();
			loader = new ProcessedSourcesLoader(manager.getWorkLoader());
			Thread.currentThread().setContextClassLoader(loader);
		}
		catch(Throwable th){
			Log.internalError("GWT preprocessor encounter a fatal error. " +
				"GWT compiller will try to run without preprocessing.\n", th);
		}
		finally{
			env.dispose();
		}
		gwtCompile(env, loader);
	}

	private static void gwtCompile(Environment env, ClassLoader loader)
			throws ClassNotFoundException, IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		Class<?> cls = loader.loadClass(GWT_COMPILER_CLASS_NAME);
		cls.getMethod("main",String[].class)
			.invoke(null,(Object)env.getCompillerArguments());
	}
}
